package serverprometheus

import (
	"context"
	prom "github.com/prometheus/client_golang/prometheus"
	"google.golang.org/grpc/status"
	"start/pkg/prometheus"
	"strconv"
	"time"

	"google.golang.org/grpc"
)

/*
两个基本指标。 1. 每个请求的耗时(histogram) 2. 每个请求的状态计数器(counter)
/user 状态码 有label 主要是状态码
*/

/*
//var serverNamespace = "start_rpc_server"

// 直方图配置
var histogramOpts prom.HistogramOpts
var labelNames = []string{"method"}
var histogramVec *prom.HistogramVec

// 创建计数器类型的指标
var counterVec *prom.CounterVec

func Init(serverNamespace string) error {
	if serverNamespace == "" {
		return errors.New("serverNamespace cannot be empty")
	}
	serverNamespace = serverNamespace + "_grpc_server"
	histogramOpts = prom.HistogramOpts{
		Namespace: serverNamespace,
		Subsystem: "requests",
		Name:      "grpc_duration_ms",
		Help:      "grpc server requests duration(ms).",
		Buckets:   []float64{5, 10, 25, 50, 100, 250, 500, 1000},
	}
	histogramVec = prometheus.NewHistogramVec(histogramOpts, labelNames)

	counterVec = prometheus.NewCounterVec(prom.CounterOpts{
		Namespace: serverNamespace,
		Subsystem: "requests",
		Name:      "grpc_code_total",
		Help:      "grpc server requests code count.",
	}, []string{"method", "code"})
	return nil
}

func UnaryPrometheusInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
	// 直方图
	histogramVec = prometheus.NewHistogramVec(histogramOpts, labelNames)

	// 执行业务
	startTime := time.Now()
	resp, err = handler(ctx, req)

	//记录了耗时
	histogramVec.WithLabelValues(info.FullMethod).Observe(float64(time.Since(startTime) / time.Millisecond))

	//记录了状态码
	counterVec.WithLabelValues(info.FullMethod, strconv.Itoa(int(status.Code(err)))).Inc()
	return resp, err
}
*/

func PrometheusInterceptor(serverNamespace string) func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
	// 直方图配置
	var histogramOpts prom.HistogramOpts
	var labelNames = []string{"method"}
	var histogramVec *prom.HistogramVec

	// 创建计数器类型的指标
	var counterVec *prom.CounterVec

	serverNamespace = serverNamespace + "_grpc_server"
	histogramOpts = prom.HistogramOpts{
		Namespace: serverNamespace,
		Subsystem: "requests",
		Name:      "grpc_duration_ms",
		Help:      "grpc server requests duration(ms).",
		Buckets:   []float64{5, 10, 25, 50, 100, 250, 500, 1000},
	}
	histogramVec = prometheus.NewHistogramVec(histogramOpts, labelNames)

	counterVec = prometheus.NewCounterVec(prom.CounterOpts{
		Namespace: serverNamespace,
		Subsystem: "requests",
		Name:      "grpc_code_total",
		Help:      "grpc server requests code count.",
	}, []string{"method", "code"})

	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
		// 直方图
		histogramVec = prometheus.NewHistogramVec(histogramOpts, labelNames)

		// 执行业务
		startTime := time.Now()
		resp, err = handler(ctx, req)

		//记录了耗时
		histogramVec.WithLabelValues(info.FullMethod).Observe(float64(time.Since(startTime) / time.Millisecond))

		//记录了状态码
		counterVec.WithLabelValues(info.FullMethod, strconv.Itoa(int(status.Code(err)))).Inc()
		return resp, err
	}
}
